<?php

class SP_ACL {
    var $acl_list = null;
    var $public_access = array('default','login');
    var $head_link = '';
    var $current_roleid = 0;
    /**
     * 初始化ACL
     *
     */
    function init($RoleID){
        $db =& Loader::database('db');
        $db->select('#roles','setting','id='.intval($RoleID));
        
        $arr = unserialize($db->getOne());
        if(!$arr){
            showError(__T('ACL table error!'));
        }
        $this->current_roleid = $RoleID;
        $this->acl_list = $arr;
    }
    /**
     * 设置公共访问权限
     *
     */
    function setPublic($arr){
        $this->public_access = $arr;
    }
    /**
     * 根据控制器，动作验证权限
     *
     */
    function checkAccess($ctrl,$act){
        if(in_array($ctrl,$this->public_access) || in_array($ctrl.'.'.$act,$this->public_access)){
            return true;
        }

        $acl  = $this->acl_list;
        
        $have_access = true;
        if(isset($acl)){
            if(isset($acl[$ctrl])){
                if(isset($acl[$ctrl.'.'.$act])){
                    if($acl[$ctrl.'.'.$act] == 0){
                        $have_access = false;
                    }
                }else{
                    if($acl[$ctrl] == 0){
                        $have_access = false;
                    }
                }
            }else{
                if(isset($acl[$ctrl.'.'.$act])){
                    if($acl[$ctrl.'.'.$act] == 0){
                        $have_access = false;
                    }
                }else{
                    $have_access = false;
                }
            }
        }else{
            $have_access = false;
        }
        unset($acl);
        
        return $have_access;
    }
    /**
     * 根据控制器验证权限
     *
     */
    function checkCtrlAccess($ctrl){
        if(in_array($ctrl,$this->public_access)){
            $this->head_link = $ctrl;
            return true;
        }

        if(isset($this->acl_list)){
            $flag = true;
            if(isset($this->acl_list[$ctrl])){
                if($this->acl_list[$ctrl] == 0){
                    $flag = false;
                }
            }else{
                $flag = false;
            }
            if($flag == false){
                foreach($this->acl_list as $key=>$value){
                    if(preg_match("/^{$ctrl}\.(.+)/is",$key)){
                        if($value == 1){
                            $head_link = $this->getFirstSubMenu($ctrl);
                            if($head_link){
                                $this->head_link = $head_link;
                            }else{
                                $this->head_link = $ctrl;
                            }
                            return true;
                        }
                    }
                }
                return false;
            }
        }else{
            return false;
        }
        $this->head_link = $ctrl;
        return true;
    }
    /**
     * 安装权限表
     *
     */
    function setupTable(){
        $db =& Loader::database('db');

        $sql[] = "CREATE TABLE IF NOT EXISTS `#modules` (
          `id` int(4) NOT NULL AUTO_INCREMENT,
          `parentID` int(4) NOT NULL DEFAULT '0' COMMENT '父模块',
          `module` varchar(30) NOT NULL COMMENT '模块',
          `moduleName` varchar(50) NOT NULL COMMENT '模块名称',
          `isShow` tinyint(1) NOT NULL DEFAULT '1' COMMENT '是否显示',
          `status` tinyint(1) NOT NULL DEFAULT '1' COMMENT '状态 1，正常 0，删除',
          `sort` int(4) NOT NULL DEFAULT '0' COMMENT '排序',
          PRIMARY KEY (`id`)
        ) ENGINE=MyISAM  DEFAULT CHARSET=utf8 COMMENT='程序模块列表' AUTO_INCREMENT=1;";
        

        $sql[] = "CREATE TABLE IF NOT EXISTS `#roles` (
          `id` int(4) NOT NULL AUTO_INCREMENT,
          `roleName` varchar(50) NOT NULL COMMENT '角色名',
          `status` tinyint(1) NOT NULL DEFAULT '1' COMMENT '状态 1，正常 0，删除',
          `setting` text NOT NULL COMMENT '权限值',
          PRIMARY KEY (`id`)
        ) ENGINE=MyISAM  DEFAULT CHARSET=utf8 COMMENT='角色表' AUTO_INCREMENT=1 ;";

        foreach($sql as $s){
            if(!$db->query($s)){
                return false;
            }
        }
        return true;
    }
    /**
     * 获取树形菜单
     */
    function getMenuTree(){
        $menu = $this->getMenu();
        if($menu){
            foreach($menu as $k => $v){
                $menu[$k]['submenu'] = $this->getSubMenu($v['module']);
            }
        }
        return $menu;
    }
    /**
     * 获取一级菜单
     *
     */
    function getMenu(){
        $cache =& Loader::lib('cache');
        $ret = $cache->get('menu_cache_'.$this->current_roleid);
        if($ret === false){
            $db =& Loader::database('db');
            $db->select('#modules','id as id,module as module,moduleName as moduleName,isShow as isShow','isShow=1 and status=1 and parentID=0 order by sort asc');
            $marr = $db->getAll();
            
            if($marr){
                $arr = null;
                foreach($marr as $v){
                    if($this->checkCtrlAccess($v['module'])){
                        $v['moduleurl'] = $this->head_link;
                        $arr[] = $v;
                    }
                }
            }else{
                $arr = null;
            }
            $cache->set('menu_cache_'.$this->current_roleid,$arr);
            return $arr;
        }
        return $ret;
    }
    
    function getFirstSubMenu($c){
        $db =& Loader::database('db');

        $db->select('#modules','id as id',"module='$c'");
        $pid = $db->getOne();
        if(!$pid){
            return false;
        }
        $db->select('#modules','id as id,module as module,moduleName as moduleName,isShow as isShow','isShow=1 and status=1 and parentID='.$pid.'  order by sort asc');
        $ret = $db->getAll();

        if($ret){
            foreach($ret as $v){
                $ctrl_act = explode('.',$v['module']);
                if($this->checkAccess($ctrl_act[0],$ctrl_act[1])){
                    return $ctrl_act[0].'/'.$ctrl_act[1];
                }
            }
            return false;
        }else{
            return false;
        }
    }
    /**
     * 获取二级菜单
     *
     */
    function getSubMenu($c = 'default'){
        $cache =& Loader::lib('cache');
        $ret = $cache->get('submenu_cache_'.$this->current_roleid);
        if($ret === false){
            $db =& Loader::database('db');
            $db->select('#modules as m left join #modules as m1 on m.parentID = m1.id','m.id as id,m.module as module,m.moduleName as moduleName,m.isShow as isShow,m1.module as parentModule','m.isShow=1 and m.status=1 and m.parentID<>0 order by m.sort asc');
            $marr = $db->getAll();
            if($marr){
                $ret = null;
                foreach($marr as $v){
                    $ctrl_act = explode('.',$v['module']);
                    if($this->checkAccess($ctrl_act[0],$ctrl_act[1])){
                        $v['moduleurl'] = $ctrl_act[0].'/'.$ctrl_act[1];
                        $ret[$v['parentModule']][] = $v;
                    }
                }
            }else{
                $ret = null;
            }
            $cache->set('submenu_cache_'.$this->current_roleid,$ret);
        }
        if($ret && isset($ret[$c])){
            return $ret[$c];
        }
        return false;
    }
    /**
     *  以下注释是控制器中所需执行的
     *  $mods = $this->getPost('selmod');
     *  $smods = $this->getPost('selsmod');
     *  if(is_array($mods)){
     *      foreach ($mods as $v){
     *          if(isset($smods[$v])) unset($smods[$v]);
     *      }
     *  }
     *  $smodsarr = array();
     *  if(is_array($smods)){
     *      foreach ($smods as $v){
     *          foreach ($v as $m){
     *              $smodsarr[] = $m;
     *          }
     *      }
     *  }
     *  unset($smods);
     *  $setting = array_merge($mods,$smodsarr);
     *  
     *  $this->acl->updatePriv($roleID,$setting);
     *
     */
    function updatePriv($roleID,$mods){
        if(count($mods) > 0){
            $db =& Loader::database('db');

            $ids = implode(',',$mods);
            $db->select('#modules','module',"id in ($ids)");
            $rs = $db->getAll();
            $setting = null;
            if($rs){
                foreach($rs as $v){
                    $setting[$v['module']] = 1;
                }
                ksort($setting);
                $db->update('#roles','id='.$roleID,array('setting'=>serialize($setting)));
                return $db->query();
            }
            return false;
        }
        return true;
    }
/*
    function getModules($roleid){
        $this->db =& Loader::database('db');
        $this->db->select('#modules','*','status=1');
        $arr = $this->db->getAll();
        
        $this->db->select('#roles','setting','id='.$roleid);
        $rights = $this->db->getOne();
        $rights = unserialize($rights);

        $pArr = array();
        if(is_array($arr)){
            $sArr = array();
            foreach ($arr as $ar){
                $ar['checked'] = false;
                if(is_array($rights)){
                     if(isset($rights[$ar['module']]) && $rights[$ar['module']]==1){
                         $ar['checked'] = true;
                     }
                }
                
                if($ar['parentID'] == 0){
                    $pArr[] = $ar;
                }else{
                    $sArr['Sub_'.$ar['parentID']][] = $ar;
                }
            }
                
            foreach ($pArr as $k=>$v){
                $pArr[$k]['Sub'] = isset($sArr['Sub_'.$v['id']])?$sArr['Sub_'.$v['id']]:array();
                if($pArr[$k]['checked'] == true){
                    foreach ($pArr[$k]['Sub'] as $kk => $vv){
                        $pArr[$k]['Sub'][$kk]['checked'] = true;
                    }
                }
            }
        }
        unset($arr);
        unset($sArr);
        return $pArr;
    }
*/
}